/*This program uses multiple hash tables of fixed size 15 for the given file.
the alpha for the last hash table is 2/3
Double hashing has been used.The function is (((sum of ascii values)/4)mod 15 + ((i*i)/2)-1))mod 15 and we move on to the next hash table after completely filling one.*/


#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<math.h>

int chk=0,flag1=0;

struct node{
char user[33];
char pass[33];
};

struct table{
struct node *next;
};

struct tables{
struct table tab[15];
struct tables *nxt;
}* first=NULL,*cur;

void create()
{   struct tables *new=malloc(sizeof(struct tables));
    int i;
    for(i=0;i<15;i++)
    {   new->tab[i].next=NULL;
        new->nxt=NULL;
    }
    if(first==NULL)
    {   first=new;
        cur=new;
    }
    else
    {   cur->nxt=new;
        cur=new;
    }
}//create

int hashprobe(int i)
{   i=((i*i)/2)-1;
    return i;
}//hashprobe

int hash(int para)
{	int loc,note,i=0;
        loc=para%15;
        note=loc;
	while(1)
        {   if(cur->tab[loc].next==NULL)
   	    {   //printf("%d",loc);
                return loc;
            }
	    else
	    {   i+=1;
                if(i==15)
                {   i=0;
                    create();
                    //printf("%d",note);
                    return note; 
                }
                else
                {   loc+=hashprobe(i);
                    loc%=15;
                }
            }
        }//while
}//hash

int search(int para,char t[33])
{   struct tables *p;
    int loc=para%15,i;
    for(p=first;p!=NULL;p=p->nxt)
    {   for(i=loc;i<15;i++)
           if(p->tab[i].next!=NULL)
           {   if(!strcmp(t,p->tab[i].next->user))
               {   cur=p;
                   return i;
               }
           }//if
        for(i=0;i<loc;i++)
           if(p->tab[i].next!=NULL)
           {   if(!strcmp(t,p->tab[i].next->user))
               {   cur=p;
                   return i;
               }
           }//if
    }//for
    printf("\nNo such userid\n");
    return -1;
}//search

void insert(char tempu[33],char temp[33],int loc)
{   struct node *new=malloc(sizeof(struct node));
    strcpy(new->user,tempu);
    strcpy(new->pass,temp);
    cur->tab[loc].next=new;
}//insert*/

void main()
{   FILE *f;
    char c[2];
    c[1]='\0';
    int asciisum=0,loc,i,j,para;
    f=fopen("user.txt","r");
    create();
    while(c[0]!=EOF)
    {   char tempu[33]="\0";
        c[0]=getc(f);
        while(c[0]!=EOF)
    	{  j=c[0];
       	   asciisum+=j;
           if(c[0]==' ')
           {   break;
           }
           else
              strcat(tempu,c);
           c[0]=getc(f);
        }//while
        char temp[33]="\0";
     	c[0]=getc(f);
     	while(c[0]!=EOF)
     	{  if(c[0]=='\n')
              break;
           else
              strcat(temp,c);
           c[0]=getc(f);
        }//while
        if(c[0]!=EOF)
           para=asciisum/4;
        loc=hash(para);
        insert(tempu,temp,loc);
    }//while
    fclose(f);
    do
    {   char temp[33];
        printf("\n\tEnter username(enter 0 to exit program):");
        scanf("%s",temp);
        if(!strcmp(temp,"0"))
        {   flag1=1;
            continue;
        }
        else
        {   asciisum=0;
            while(temp[i]!='\0')
            {   j=temp[i];
                asciisum+=j;
                i++;
            }//while
            para=asciisum/4;
            i=search(para,temp);
            if(i==-1)
              continue;
            int flag=0;
            do
            {   printf("\n\tEnter password:");
                scanf("%s",temp);      
                if(!strcmp(temp,cur->tab[i].next->pass))
                {   printf("\nUsername and password match\n");
                    flag=1;
                }
                else
                {   printf("\nIncorrect password\n"); 
                    chk+=1;
                    if(chk==3)
                    {   flag=1;
                        chk=0;
                        printf("Too many incorrect attempts,access is forbidden\n");
                    }
                }
            }while(flag!=1);
        }//else
     }while(flag1!=1);
}//main




